1 /*
2  * This file is part of gtkD.
3  *
4  * gtkD is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License
6  * as published by the Free Software Foundation; either version 3
7  * of the License, or (at your option) any later version, with
8  * some exceptions, please read the COPYING file.
9  *
10  * gtkD is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with gtkD; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
18  */
19 
20 // generated automatically - do not change
21 // find conversion definition on APILookup.txt
22 // implement new conversion functionalities on the wrap.utils pakage
23 
24 
25 module gdk.Surface;
26 
27 private import cairo.Region;
28 private import cairo.Surface : CairoSurface = Surface;
29 private import gdk.CairoContext;
30 private import gdk.Cursor;
31 private import gdk.Device;
32 private import gdk.Display;
33 private import gdk.Event;
34 private import gdk.FrameClock;
35 private import gdk.GLContext;
36 private import gdk.MonitorGdk;
37 private import gdk.VulkanContext;
38 private import gdk.c.functions;
39 public  import gdk.c.types;
40 private import glib.ConstructionException;
41 private import glib.ErrorG;
42 private import glib.GException;
43 private import gobject.ObjectG;
44 private import gobject.Signals;
45 private import std.algorithm;
46 
47 
48 /**
49  * A `GdkSurface` is a rectangular region on the screen.
50  * 
51  * It’s a low-level object, used to implement high-level objects
52  * such as [class@Gtk.Window] or [class@Gtk.Dialog] in GTK.
53  * 
54  * The surfaces you see in practice are either [iface@Gdk.Toplevel] or
55  * [iface@Gdk.Popup], and those interfaces provide much of the required
56  * API to interact with these surfaces. Other, more specialized surface
57  * types exist, but you will rarely interact with them directly.
58  */
59 public class Surface : ObjectG
60 {
61 	/** the main Gtk struct */
62 	protected GdkSurface* gdkSurface;
63 
64 	/** Get the main Gtk struct */
65 	public GdkSurface* getSurfaceStruct(bool transferOwnership = false)
66 	{
67 		if (transferOwnership)
68 			ownedRef = false;
69 		return gdkSurface;
70 	}
71 
72 	/** the main Gtk struct as a void* */
73 	protected override void* getStruct()
74 	{
75 		return cast(void*)gdkSurface;
76 	}
77 
78 	/**
79 	 * Sets our main struct and passes it to the parent class.
80 	 */
81 	public this (GdkSurface* gdkSurface, bool ownedRef = false)
82 	{
83 		this.gdkSurface = gdkSurface;
84 		super(cast(GObject*)gdkSurface, ownedRef);
85 	}
86 
87 
88 	/** */
89 	public static GType getType()
90 	{
91 		return gdk_surface_get_type();
92 	}
93 
94 	/**
95 	 * Create a new popup surface.
96 	 *
97 	 * The surface will be attached to @parent and can be positioned
98 	 * relative to it using [method@Gdk.Popup.present].
99 	 *
100 	 * Params:
101 	 *     parent = the parent surface to attach the surface to
102 	 *     autohide = whether to hide the surface on outside clicks
103 	 *
104 	 * Returns: a new `GdkSurface`
105 	 *
106 	 * Throws: ConstructionException GTK+ fails to create the object.
107 	 */
108 	public this(Surface parent, bool autohide)
109 	{
110 		auto __p = gdk_surface_new_popup((parent is null) ? null : parent.getSurfaceStruct(), autohide);
111 
112 		if(__p is null)
113 		{
114 			throw new ConstructionException("null returned by new_popup");
115 		}
116 
117 		this(cast(GdkSurface*) __p, true);
118 	}
119 
120 	/**
121 	 * Creates a new toplevel surface.
122 	 *
123 	 * Params:
124 	 *     display = the display to create the surface on
125 	 *
126 	 * Returns: the new `GdkSurface`
127 	 *
128 	 * Throws: ConstructionException GTK+ fails to create the object.
129 	 */
130 	public this(Display display)
131 	{
132 		auto __p = gdk_surface_new_toplevel((display is null) ? null : display.getDisplayStruct());
133 
134 		if(__p is null)
135 		{
136 			throw new ConstructionException("null returned by new_toplevel");
137 		}
138 
139 		this(cast(GdkSurface*) __p, true);
140 	}
141 
142 	/**
143 	 * Emits a short beep associated to @surface.
144 	 *
145 	 * If the display of @surface does not support per-surface beeps,
146 	 * emits a short beep on the display just as [method@Gdk.Display.beep].
147 	 */
148 	public void beep()
149 	{
150 		gdk_surface_beep(gdkSurface);
151 	}
152 
153 	/**
154 	 * Creates a new `GdkCairoContext` for rendering on @surface.
155 	 *
156 	 * Returns: the newly created `GdkCairoContext`
157 	 */
158 	public CairoContext createCairoContext()
159 	{
160 		auto __p = gdk_surface_create_cairo_context(gdkSurface);
161 
162 		if(__p is null)
163 		{
164 			return null;
165 		}
166 
167 		return ObjectG.getDObject!(CairoContext)(cast(GdkCairoContext*) __p, true);
168 	}
169 
170 	/**
171 	 * Creates a new `GdkGLContext` for the `GdkSurface`.
172 	 *
173 	 * The context is disconnected from any particular surface or surface.
174 	 * If the creation of the `GdkGLContext` failed, @error will be set.
175 	 * Before using the returned `GdkGLContext`, you will need to
176 	 * call [method@Gdk.GLContext.make_current] or [method@Gdk.GLContext.realize].
177 	 *
178 	 * Returns: the newly created `GdkGLContext`
179 	 *
180 	 * Throws: GException on failure.
181 	 */
182 	public GLContext createGlContext()
183 	{
184 		GError* err = null;
185 
186 		auto __p = gdk_surface_create_gl_context(gdkSurface, &err);
187 
188 		if (err !is null)
189 		{
190 			throw new GException( new ErrorG(err) );
191 		}
192 
193 		if(__p is null)
194 		{
195 			return null;
196 		}
197 
198 		return ObjectG.getDObject!(GLContext)(cast(GdkGLContext*) __p, true);
199 	}
200 
201 	/**
202 	 * Create a new Cairo surface that is as compatible as possible with the
203 	 * given @surface.
204 	 *
205 	 * For example the new surface will have the same fallback resolution
206 	 * and font options as @surface. Generally, the new surface will also
207 	 * use the same backend as @surface, unless that is not possible for
208 	 * some reason. The type of the returned surface may be examined with
209 	 * cairo_surface_get_type().
210 	 *
211 	 * Initially the surface contents are all 0 (transparent if contents
212 	 * have transparency, black otherwise.)
213 	 *
214 	 * This function always returns a valid pointer, but it will return a
215 	 * pointer to a “nil” surface if @other is already in an error state
216 	 * or any other error occurs.
217 	 *
218 	 * Params:
219 	 *     content = the content for the new surface
220 	 *     width = width of the new surface
221 	 *     height = height of the new surface
222 	 *
223 	 * Returns: a pointer to the newly allocated surface. The caller
224 	 *     owns the surface and should call cairo_surface_destroy() when done
225 	 *     with it.
226 	 */
227 	public CairoSurface createSimilarSurface(cairo_content_t content, int width, int height)
228 	{
229 		auto __p = gdk_surface_create_similar_surface(gdkSurface, content, width, height);
230 
231 		if(__p is null)
232 		{
233 			return null;
234 		}
235 
236 		return new CairoSurface(cast(cairo_surface_t*) __p);
237 	}
238 
239 	/**
240 	 * Creates a new `GdkVulkanContext` for rendering on @surface.
241 	 *
242 	 * If the creation of the `GdkVulkanContext` failed, @error will be set.
243 	 *
244 	 * Returns: the newly created `GdkVulkanContext`, or
245 	 *     %NULL on error
246 	 *
247 	 * Throws: GException on failure.
248 	 */
249 	public VulkanContext createVulkanContext()
250 	{
251 		GError* err = null;
252 
253 		auto __p = gdk_surface_create_vulkan_context(gdkSurface, &err);
254 
255 		if (err !is null)
256 		{
257 			throw new GException( new ErrorG(err) );
258 		}
259 
260 		if(__p is null)
261 		{
262 			return null;
263 		}
264 
265 		return ObjectG.getDObject!(VulkanContext)(cast(GdkVulkanContext*) __p, true);
266 	}
267 
268 	/**
269 	 * Destroys the window system resources associated with @surface and
270 	 * decrements @surface's reference count.
271 	 *
272 	 * The window system resources for all children of @surface are also
273 	 * destroyed, but the children’s reference counts are not decremented.
274 	 *
275 	 * Note that a surface will not be destroyed automatically when its
276 	 * reference count reaches zero. You must call this function yourself
277 	 * before that happens.
278 	 */
279 	public void destroy()
280 	{
281 		gdk_surface_destroy(gdkSurface);
282 	}
283 
284 	/**
285 	 * Retrieves a `GdkCursor` pointer for the cursor currently set on the
286 	 * `GdkSurface`.
287 	 *
288 	 * If the return value is %NULL then there is no custom cursor set on
289 	 * the surface, and it is using the cursor for its parent surface.
290 	 *
291 	 * Use [method@Gdk.Surface.set_cursor] to unset the cursor of the surface.
292 	 *
293 	 * Returns: a `GdkCursor`
294 	 */
295 	public Cursor getCursor()
296 	{
297 		auto __p = gdk_surface_get_cursor(gdkSurface);
298 
299 		if(__p is null)
300 		{
301 			return null;
302 		}
303 
304 		return ObjectG.getDObject!(Cursor)(cast(GdkCursor*) __p);
305 	}
306 
307 	/**
308 	 * Retrieves a `GdkCursor` pointer for the @device currently set on the
309 	 * specified `GdkSurface`.
310 	 *
311 	 * If the return value is %NULL then there is no custom cursor set on the
312 	 * specified surface, and it is using the cursor for its parent surface.
313 	 *
314 	 * Use [method@Gdk.Surface.set_cursor] to unset the cursor of the surface.
315 	 *
316 	 * Params:
317 	 *     device = a pointer `GdkDevice`
318 	 *
319 	 * Returns: a `GdkCursor`
320 	 */
321 	public Cursor getDeviceCursor(Device device)
322 	{
323 		auto __p = gdk_surface_get_device_cursor(gdkSurface, (device is null) ? null : device.getDeviceStruct());
324 
325 		if(__p is null)
326 		{
327 			return null;
328 		}
329 
330 		return ObjectG.getDObject!(Cursor)(cast(GdkCursor*) __p);
331 	}
332 
333 	/**
334 	 * Obtains the current device position and modifier state.
335 	 *
336 	 * The position is given in coordinates relative to the upper
337 	 * left corner of @surface.
338 	 *
339 	 * Params:
340 	 *     device = pointer `GdkDevice` to query to
341 	 *     x = return location for the X coordinate of @device
342 	 *     y = return location for the Y coordinate of @device
343 	 *     mask = return location for the modifier mask
344 	 *
345 	 * Returns: %TRUE if the device is over the surface
346 	 */
347 	public bool getDevicePosition(Device device, out double x, out double y, out GdkModifierType mask)
348 	{
349 		return gdk_surface_get_device_position(gdkSurface, (device is null) ? null : device.getDeviceStruct(), &x, &y, &mask) != 0;
350 	}
351 
352 	/**
353 	 * Gets the `GdkDisplay` associated with a `GdkSurface`.
354 	 *
355 	 * Returns: the `GdkDisplay` associated with @surface
356 	 */
357 	public Display getDisplay()
358 	{
359 		auto __p = gdk_surface_get_display(gdkSurface);
360 
361 		if(__p is null)
362 		{
363 			return null;
364 		}
365 
366 		return ObjectG.getDObject!(Display)(cast(GdkDisplay*) __p);
367 	}
368 
369 	/**
370 	 * Gets the frame clock for the surface.
371 	 *
372 	 * The frame clock for a surface never changes unless the surface is
373 	 * reparented to a new toplevel surface.
374 	 *
375 	 * Returns: the frame clock
376 	 */
377 	public FrameClock getFrameClock()
378 	{
379 		auto __p = gdk_surface_get_frame_clock(gdkSurface);
380 
381 		if(__p is null)
382 		{
383 			return null;
384 		}
385 
386 		return ObjectG.getDObject!(FrameClock)(cast(GdkFrameClock*) __p);
387 	}
388 
389 	/**
390 	 * Returns the height of the given @surface.
391 	 *
392 	 * Surface size is reported in ”application pixels”, not
393 	 * ”device pixels” (see [method@Gdk.Surface.get_scale_factor]).
394 	 *
395 	 * Returns: The height of @surface
396 	 */
397 	public int getHeight()
398 	{
399 		return gdk_surface_get_height(gdkSurface);
400 	}
401 
402 	/**
403 	 * Checks whether the surface has been mapped.
404 	 *
405 	 * A surface is mapped with [method@Gdk.Toplevel.present]
406 	 * or [method@Gdk.Popup.present].
407 	 *
408 	 * Returns: %TRUE if the surface is mapped
409 	 */
410 	public bool getMapped()
411 	{
412 		return gdk_surface_get_mapped(gdkSurface) != 0;
413 	}
414 
415 	/**
416 	 * Returns the internal scale factor that maps from surface coordinates
417 	 * to the actual device pixels.
418 	 *
419 	 * On traditional systems this is 1, but on very high density outputs
420 	 * this can be a higher value (often 2). A higher value means that drawing
421 	 * is automatically scaled up to a higher resolution, so any code doing
422 	 * drawing will automatically look nicer. However, if you are supplying
423 	 * pixel-based data the scale value can be used to determine whether to
424 	 * use a pixel resource with higher resolution data.
425 	 *
426 	 * The scale of a surface may change during runtime.
427 	 *
428 	 * Returns: the scale factor
429 	 */
430 	public int getScaleFactor()
431 	{
432 		return gdk_surface_get_scale_factor(gdkSurface);
433 	}
434 
435 	/**
436 	 * Returns the width of the given @surface.
437 	 *
438 	 * Surface size is reported in ”application pixels”, not
439 	 * ”device pixels” (see [method@Gdk.Surface.get_scale_factor]).
440 	 *
441 	 * Returns: The width of @surface
442 	 */
443 	public int getWidth()
444 	{
445 		return gdk_surface_get_width(gdkSurface);
446 	}
447 
448 	/**
449 	 * Hide the surface.
450 	 *
451 	 * For toplevel surfaces, withdraws them, so they will no longer be
452 	 * known to the window manager; for all surfaces, unmaps them, so
453 	 * they won’t be displayed. Normally done automatically as
454 	 * part of [method@Gtk.Widget.hide].
455 	 */
456 	public void hide()
457 	{
458 		gdk_surface_hide(gdkSurface);
459 	}
460 
461 	/**
462 	 * Check to see if a surface is destroyed.
463 	 *
464 	 * Returns: %TRUE if the surface is destroyed
465 	 */
466 	public bool isDestroyed()
467 	{
468 		return gdk_surface_is_destroyed(gdkSurface) != 0;
469 	}
470 
471 	/**
472 	 * Forces a [signal@Gdk.Surface::render] signal emission for @surface
473 	 * to be scheduled.
474 	 *
475 	 * This function is useful for implementations that track invalid
476 	 * regions on their own.
477 	 */
478 	public void queueRender()
479 	{
480 		gdk_surface_queue_render(gdkSurface);
481 	}
482 
483 	/**
484 	 * Request a layout phase from the surface's frame clock.
485 	 *
486 	 * See [method@Gdk.FrameClock.request_phase].
487 	 */
488 	public void requestLayout()
489 	{
490 		gdk_surface_request_layout(gdkSurface);
491 	}
492 
493 	/**
494 	 * Sets the default mouse pointer for a `GdkSurface`.
495 	 *
496 	 * Passing %NULL for the @cursor argument means that @surface will use
497 	 * the cursor of its parent surface. Most surfaces should use this default.
498 	 * Note that @cursor must be for the same display as @surface.
499 	 *
500 	 * Use [ctor@Gdk.Cursor.new_from_name] or [ctor@Gdk.Cursor.new_from_texture]
501 	 * to create the cursor. To make the cursor invisible, use %GDK_BLANK_CURSOR.
502 	 *
503 	 * Params:
504 	 *     cursor = a `GdkCursor`
505 	 */
506 	public void setCursor(Cursor cursor)
507 	{
508 		gdk_surface_set_cursor(gdkSurface, (cursor is null) ? null : cursor.getCursorStruct());
509 	}
510 
511 	/**
512 	 * Sets a specific `GdkCursor` for a given device when it gets inside @surface.
513 	 *
514 	 * Passing %NULL for the @cursor argument means that @surface will use the
515 	 * cursor of its parent surface. Most surfaces should use this default.
516 	 *
517 	 * Use [ctor@Gdk.Cursor.new_from_name] or [ctor@Gdk.Cursor.new_from_texture]
518 	 * to create the cursor. To make the cursor invisible, use %GDK_BLANK_CURSOR.
519 	 *
520 	 * Params:
521 	 *     device = a pointer `GdkDevice`
522 	 *     cursor = a `GdkCursor`
523 	 */
524 	public void setDeviceCursor(Device device, Cursor cursor)
525 	{
526 		gdk_surface_set_device_cursor(gdkSurface, (device is null) ? null : device.getDeviceStruct(), (cursor is null) ? null : cursor.getCursorStruct());
527 	}
528 
529 	/**
530 	 * Apply the region to the surface for the purpose of event
531 	 * handling.
532 	 *
533 	 * Mouse events which happen while the pointer position corresponds
534 	 * to an unset bit in the mask will be passed on the surface below
535 	 * @surface.
536 	 *
537 	 * An input region is typically used with RGBA surfaces. The alpha
538 	 * channel of the surface defines which pixels are invisible and
539 	 * allows for nicely antialiased borders, and the input region
540 	 * controls where the surface is “clickable”.
541 	 *
542 	 * Use [method@Gdk.Display.supports_input_shapes] to find out if
543 	 * a particular backend supports input regions.
544 	 *
545 	 * Params:
546 	 *     region = region of surface to be reactive
547 	 */
548 	public void setInputRegion(Region region)
549 	{
550 		gdk_surface_set_input_region(gdkSurface, (region is null) ? null : region.getRegionStruct());
551 	}
552 
553 	/**
554 	 * Marks a region of the `GdkSurface` as opaque.
555 	 *
556 	 * For optimisation purposes, compositing window managers may
557 	 * like to not draw obscured regions of surfaces, or turn off blending
558 	 * during for these regions. With RGB windows with no transparency,
559 	 * this is just the shape of the window, but with ARGB32 windows, the
560 	 * compositor does not know what regions of the window are transparent
561 	 * or not.
562 	 *
563 	 * This function only works for toplevel surfaces.
564 	 *
565 	 * GTK will update this property automatically if the @surface background
566 	 * is opaque, as we know where the opaque regions are. If your surface
567 	 * background is not opaque, please update this property in your
568 	 * [vfunc@Gtk.Widget.css_changed] handler.
569 	 *
570 	 * Params:
571 	 *     region = a region, or %NULL to make the entire
572 	 *         surface opaque
573 	 */
574 	public void setOpaqueRegion(Region region)
575 	{
576 		gdk_surface_set_opaque_region(gdkSurface, (region is null) ? null : region.getRegionStruct());
577 	}
578 
579 	/**
580 	 * Translates coordinates between two surfaces.
581 	 *
582 	 * Note that this only works if @to and @from are popups or
583 	 * transient-for to the same toplevel (directly or indirectly).
584 	 *
585 	 * Params:
586 	 *     to = the target surface
587 	 *     x = coordinates to translate
588 	 *     y = coordinates to translate
589 	 *
590 	 * Returns: %TRUE if the coordinates were successfully translated
591 	 */
592 	public bool translateCoordinates(Surface to, ref double x, ref double y)
593 	{
594 		return gdk_surface_translate_coordinates(gdkSurface, (to is null) ? null : to.getSurfaceStruct(), &x, &y) != 0;
595 	}
596 
597 	/**
598 	 * Emitted when @surface starts being present on the monitor.
599 	 *
600 	 * Params:
601 	 *     monitor = the monitor
602 	 */
603 	gulong addOnEnterMonitor(void delegate(MonitorGdk, Surface) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
604 	{
605 		return Signals.connect(this, "enter-monitor", dlg, connectFlags ^ ConnectFlags.SWAPPED);
606 	}
607 
608 	/**
609 	 * Emitted when GDK receives an input event for @surface.
610 	 *
611 	 * Params:
612 	 *     event = an input event
613 	 *
614 	 * Returns: %TRUE to indicate that the event has been handled
615 	 */
616 	gulong addOnEvent(bool delegate(Event, Surface) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
617 	{
618 		return Signals.connect(this, "event", dlg, connectFlags ^ ConnectFlags.SWAPPED);
619 	}
620 
621 	/**
622 	 * Emitted when the size of @surface is changed, or when relayout should
623 	 * be performed.
624 	 *
625 	 * Surface size is reported in ”application pixels”, not
626 	 * ”device pixels” (see gdk_surface_get_scale_factor()).
627 	 *
628 	 * Params:
629 	 *     width = the current width
630 	 *     height = the current height
631 	 */
632 	gulong addOnLayout(void delegate(int, int, Surface) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
633 	{
634 		return Signals.connect(this, "layout", dlg, connectFlags ^ ConnectFlags.SWAPPED);
635 	}
636 
637 	/**
638 	 * Emitted when @surface stops being present on the monitor.
639 	 *
640 	 * Params:
641 	 *     monitor = the monitor
642 	 */
643 	gulong addOnLeaveMonitor(void delegate(MonitorGdk, Surface) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
644 	{
645 		return Signals.connect(this, "leave-monitor", dlg, connectFlags ^ ConnectFlags.SWAPPED);
646 	}
647 
648 	/**
649 	 * Emitted when part of the surface needs to be redrawn.
650 	 *
651 	 * Params:
652 	 *     region = the region that needs to be redrawn
653 	 *
654 	 * Returns: %TRUE to indicate that the signal has been handled
655 	 */
656 	gulong addOnRender(bool delegate(Region, Surface) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
657 	{
658 		return Signals.connect(this, "render", dlg, connectFlags ^ ConnectFlags.SWAPPED);
659 	}
660 }